page.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import Link from 'next/link';
  2. import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
  3. import { Button } from '@/components/ui/button';
  4. import { Mail, CheckCircle } from 'lucide-react';
  5. import { useTranslations } from "next-intl";
  6. import { Metadata } from "next";
  7. import { getTranslations, setRequestLocale } from "next-intl/server";
  8. import ResendVerificationEmail from './resend-verification-email';
  9. import Navigation from "@/components/navigation";
  10. import Footer from "@/components/footer";
  11. interface VerifyEmailSentPageProps {
  12. params: Promise<{
  13. locale: string;
  14. }>;
  15. searchParams?: {
  16. email?: string;
  17. };
  18. }
  19. export async function generateMetadata({ params }: VerifyEmailSentPageProps): Promise<Metadata> {
  20. const { locale } = await params;
  21. const t = await getTranslations({ locale, namespace: 'auth.verifyEmailSent' });
  22. return {
  23. title: t('pageTitle'),
  24. };
  25. }
  26. export default async function VerifyEmailSentPage({ params, searchParams }: VerifyEmailSentPageProps) {
  27. const { locale } = await params;
  28. // 启用静态渲染
  29. setRequestLocale(locale);
  30. const t = await getTranslations('auth.verifyEmailSent');
  31. const email = searchParams?.email;
  32. return (
  33. <>
  34. <Navigation locale={locale} />
  35. <div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
  36. <div className="max-w-md w-full space-y-8">
  37. <div className="text-center">
  38. <div className="mx-auto flex items-center justify-center h-20 w-20 rounded-full bg-green-100">
  39. <svg className="h-10 w-10 text-green-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
  40. <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 4.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
  41. </svg>
  42. </div>
  43. <h2 className="mt-6 text-3xl font-extrabold text-gray-900">
  44. {t('title')}
  45. </h2>
  46. <p className="mt-2 text-sm text-gray-600">
  47. {t('message')}
  48. </p>
  49. {email && (
  50. <p className="mt-2 text-sm text-blue-600 font-medium">
  51. {email}
  52. </p>
  53. )}
  54. </div>
  55. <div className="bg-white p-6 rounded-lg shadow">
  56. <div className="space-y-4">
  57. <div className="bg-blue-50 p-4 rounded-lg">
  58. <h3 className="text-sm font-medium text-blue-800 mb-2">
  59. {t('stepsTitle')}
  60. </h3>
  61. <ol className="text-sm text-blue-700 space-y-1">
  62. <li>1. {t('step1')}</li>
  63. <li>2. {t('step2')}</li>
  64. <li>3. {t('step3')}</li>
  65. <li>4. {t('step4')}</li>
  66. </ol>
  67. </div>
  68. <div className="text-center text-sm text-gray-600">
  69. <p>{t('checkSpam')}</p>
  70. </div>
  71. {/* 重发验证邮件组件 */}
  72. {email && (
  73. <ResendVerificationEmail email={email} locale={locale} />
  74. )}
  75. <div className="flex flex-col space-y-3 pt-4 border-t">
  76. <a
  77. href={`/${locale}/auth/login`}
  78. className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
  79. >
  80. {t('backToLogin')}
  81. </a>
  82. <a
  83. href={`/${locale}/auth/register`}
  84. className="w-full flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
  85. >
  86. {t('differentEmail')}
  87. </a>
  88. </div>
  89. </div>
  90. </div>
  91. </div>
  92. </div>
  93. <Footer locale={locale} />
  94. </>
  95. );
  96. }